// @Author EthanScriptOn
// @Desc
package config_freighter

import (
	"errors"
	"gitee.com/fatzeng/srf_switch_basic_components/node"
	"gitee.com/fatzeng/srf_switch_basic_components/processor"
	"gitee.com/fatzeng/srf_switch_config/config_context"
	"gitee.com/fatzeng/srf_switch_config/config_node"
	"gitee.com/fatzeng/srf_switch_config/config_processor_management"
)

func StartFreight(ctx *config_context.ConfigInitializationContext) (err error) {
	if err = ctx.GetResultCoordinator().Sort(); err != nil {
		return
	}
	mergedResult, err := ObtainMergedProcessResult(ctx.GetResultCoordinator().GetProcessedResult())
	if err != nil {
		return
	}
	processor, err := GetFreightProcessor()
	if err != nil {
		return
	}
	return processor.Process(ctx, mergedResult)
}

func ObtainMergedProcessResult(processParseResult *config_node.ParseResultPackageNode) (map[string]interface{}, error) {
	mergedResult := make(map[string]interface{})
	return MergedProcessResult(processParseResult, mergedResult)
}

func MergedProcessResult(processParseResult *config_node.ParseResultPackageNode, mergedResult map[string]interface{}) (map[string]interface{}, error) {
	for elemType, elemVal := range processParseResult.GetGroupResult() {
		mergedResult[string(elemType)] = elemVal
	}
	adjacentNode, hasAdjacentNode, err := processParseResult.GetAdjacentNode(node.TAIL)
	if err != nil {
		return nil, err
	}
	if !hasAdjacentNode {
		return mergedResult, nil
	}
	packageNode, ok := adjacentNode.(*config_node.ParseResultPackageNode)
	if !ok {
		return nil, errors.New("adjacentNode can not convert to *ParseResultPackageNode")
	}
	return MergedProcessResult(packageNode, mergedResult)
}

func GetFreightProcessor() (processor.Processor, error) {
	processorManager, err := config_processor_management.GetFreightProcessorManager()
	if err != nil {
		return nil, err
	}
	return processorManager.GetAppropriateProcessor(config_processor_management.FreightIdentifier)
}
